#include <stdio.h>
#include <stdlib.h>
#include "load.h"

int main (int argc, char * argv[]) {
	if (argc != 2) {
		printf("Mauvais nombre d'arguments.\n");
		return 0;
	} 
	if (!estELF(argv[1])) {
		printf("Le fichier en argument doit être un .o\n");
		return 0;
	}
	int i;
	FILE * f = fopen(argv[1], "r");
	Elf32_Ehdr header = load_header(f);
	printf("ELF Header :\n");

	// MAGIC
	printf("   Magic : ");
	for (i = 0; i < 15; i++) {
		printf("%x ", header.e_ident[i]);
	} 
	printf("%x\n", header.e_ident[15]);

	//CLASS
	printf("   Class : ");
	if ((int)header.e_ident[4] == 0) {
		printf("Invalid class\n");
	} else if ((int)header.e_ident[4] == 1) {
		printf("ELF32\n");
	} else {
		printf("ELF64\n");
	} 

	//DATA
	printf("   Data : ");
	if ((int)header.e_ident[5] == 0) {
		printf("Invalid data encoding\n");
	} else if ((int)header.e_ident[5] == 1) {
		printf("2's complement, little endian\n");
	} else {
		printf("2's complement, big endian\n");
	} 

	//Version
	printf("   Version : %d \n", header.e_ident[6]);

	//OS/ABI
	printf("   OS/ABI : ");
	if ((int)header.e_ident[7] == 0) {
		printf("UNIX - System V\n");
	} else if ((int)header.e_ident[7] == 1) {
		printf("HP-UX operating system\n");
	} else {
		printf("Standalone (embedded) application\n");
	} 

	//ABI VERSION
	printf("   ABI Version : %d\n", header.e_ident[8]);
	
	//TYPE
	printf("   Type : ");
	if (header.e_type == 0) {
		printf("NONE (No file type)\n");
	} else if (header.e_type == 1) {
		printf("REL (Relocatable file)\n");
	} else if (header.e_type == 2) {
		printf("EXEC (Executable file)\n");
	} else if (header.e_type == 3) {
		printf("DYN (Shared object file)\n");
	} else if (header.e_type == 4) {
		printf("CORE (Core file)\n");
	} else if (header.e_type == 0xff00) {
		printf("LOPROC (Processor-specific)\n");
	} else if (header.e_type == 0xffff){
		printf("HIPROC (Processor-specific)\n");
	} else {
		printf("\n");
	}

	//MACHINE
	printf("   Machine : ");
	if (header.e_machine == 0) {
		printf("No machine\n");
	} else if (header.e_machine == 1) {
		printf("AT&T WE 32100\n");
	} else if (header.e_machine == 2) {
		printf("SPARC\n");
	} else if (header.e_machine == 3) {
		printf("Intel 80386\n");
	} else if (header.e_machine == 4) {
		printf("Motorola 68000\n");
	} else if (header.e_machine == 5) {
		printf("Motorola 88000\n");
	} else if (header.e_machine == 7) {
		printf("Intel 80860\n");
	} else if (header.e_machine == 8) {
		printf("MIPS RS3000\n");
	} else if (header.e_machine == 40) {
		printf("ARM\n");
	}  else {
		printf("\n");
	}

	//VERSION
	printf("   Version : 0x%lx\n", (long unsigned int)header.e_version);

	//ENTRY POINT ADRESS
	printf("   Entry point adress : 0x%lx\n", (long unsigned int)header.e_entry);

	//START OF PROGRAMS HEADERS
	printf("   Start of program headers : %ld \n", (long  int)header.e_phoff);

	//START OF SECTION HEADERS
	printf("   Start of section headers : %ld \n", (long  int)header.e_shoff);

	//FLAGS
	printf("   Flags  : 0x%lx\n", (long unsigned int)header.e_flags);

	//SIZE OF THIS HEADER
	printf("   Size of this header  : %d\n", header.e_ehsize);

	//SIZE OF PROGRAM HEADER
	printf("   Size of program header  : %d\n", header.e_phentsize);
	
	//NUMBER OF PROGRAM HEADER
	printf("   Number of program header  : %d\n", header.e_phnum);

	//SIZE OF SECTION HEADER
	printf("   Size of section header  : %d\n", header.e_shentsize);

	//NUMBER OF SECTIONS HEADERS
	printf("   Number of section header  : %d\n", header.e_shnum);

	//SECTION HEADER STRING TABLE INDEX
	printf("   Section header string table index  : %d\n", header.e_shstrndx);

	fclose(f);
	return 0;  
}
